package br.com.upis.sispat.view;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.model.SelectItem;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import br.com.upis.sispat.entity.Usuario;
import br.com.upis.sispat.enums.Perfil;
import br.com.upis.sispat.enums.StatusAtivo;
import br.com.upis.sispat.enums.UF;
import br.com.upis.sispat.exception.SeamCoreException;
import br.com.upis.sispat.exception.SeamWebException;
import br.com.upis.sispat.service.UsuarioService;

@Component
@Scope("singleton")
public class UsuarioView extends AbstractView implements ICommandPopup {

	private static final long serialVersionUID = -993431214631653901L;
	private static final String PATH_LISTAR_USUARIO = CONTEXT	+ "/usuario/listarUsuario";
	private static final String PATH_EDITAR_USUARIO = CONTEXT	+ "/usuario/editarUsuario";
	private static final String PATH_DETALHAR_USUARIO = CONTEXT	+ "/usuario/detalharUsuario";

	private List<Usuario> listaUsuario;
	private Usuario usuario;
	private Usuario usuarioPesquisa;
	private SelectItem[] listaPerfil;
	private SelectItem[] listaStatus;
	private UsuarioService usuarioService;
	private Usuario usuarioLogado;
	private boolean desabilitaCadastro;
	private String confirmacaoSenha;
	private boolean desabilitaCadastroPerfil;
	private String senhaDigitada;
	private String confirmacaoSenhaDigitada;

	@PostConstruct
	public void init() {

		setUsuario(new Usuario());
		setExibePopup(false);
		setSenhaDigitada(null);
		setConfirmacaoSenhaDigitada(null);
		senhaDigitada = "";
		confirmacaoSenhaDigitada = "";

		setExibeMsgNenhumRegistroEncontrado(false);
	}

	public String iniciar() {

		init();

		setUsuarioPesquisa(new Usuario());
		getUsuarioPesquisa().setStatus("S");

		setListaUsuario(new ArrayList<Usuario>());

		setUsuarioLogado(recuperaUsuarioLogado());
		setSenhaDigitada(getUsuarioLogado().getSenha());
		setConfirmacaoSenhaDigitada(getUsuarioLogado().getSenha());

		return redirecionaUsuarioAcesso(PATH_LISTAR_USUARIO);
	}

	public String voltar() throws SeamWebException {

		if (!getListaUsuario().isEmpty()) {
			try {
				setListaUsuario(usuarioService.search(getUsuarioPesquisa()));
			} catch (SeamCoreException e) {
				throw new SeamWebException(e);
			}
		} else {
			init();
		}

		return PATH_LISTAR_USUARIO;
	}

	private String redirecionaUsuarioAcesso(String path) {

		if (possuiAcesso(getUsuarioLogado().getPerfil())) {
			setUsuario(getUsuarioLogado());
			setDesabilitaCadastro(true);
			setConfirmacaoSenha(getUsuario().getSenha());
			return PATH_EDITAR_USUARIO;
		}

		setDesabilitaCadastro(false);

		if (getListaUsuario().isEmpty()) {

			return path;
		}

		return pesquisar();
	}

	public String pesquisar() {
		getUsuarioPesquisa().getSetor().setCodigo(1L);

		try {
			setListaUsuario(usuarioService.search(getUsuarioPesquisa()));
		} catch (SeamCoreException e) {

			e.printStackTrace();
		}
		setExibeMsgNenhumRegistroEncontrado(getListaUsuario().isEmpty());
		return PATH_LISTAR_USUARIO;
	}

	public String novo() {

		if (!isExibePopup()) {
			init();

			setConfirmacaoSenha("");

			getUsuario().setStatus(StatusAtivo.STATUS_ATIVO.getValor());

			setDesabilitaCadastroPerfil(false);
		} else {
			// Como os campos de senha e Confirmação de senha são "inputSecret"
			// os mesmos não guardam o valor depois de submeter
			// Portanto ao se mostrar a mensagem "Confirma Inclusão?" o valor é
			// perdido, por isso da criação destas duas variáveis

			setSenhaDigitada(getUsuario().getSenha());
			setConfirmacaoSenhaDigitada(getConfirmacaoSenha());
		}

		return PATH_EDITAR_USUARIO;
	}

	public String detalhar() {

		getUsuario().setPerfil(
				Perfil.getPerfilByCodigo(getUsuario().getIdAcesso()));

		return PATH_DETALHAR_USUARIO;
	}

	public String editar() throws SeamWebException {
		try {
			if (!isExibePopup()) {
				setUsuario(usuarioService.getById(usuario.getCodigo()));
			}
			if (!getSenhaDigitada().equals("")) {
				setSenhaDigitada(usuario.getSenha());
				setConfirmacaoSenhaDigitada(getSenhaDigitada());
			} else {
				usuario.setSenha(getSenhaDigitada());
			}
			
			if(getUsuario().getPerfil()!=null){
				usuario.setIdAcesso(usuario.getPerfil().getCodigoPerfil());
			}

			if (getUsuario().getIdAcesso() != null) {
				getUsuario().setPerfil(
						Perfil.getPerfilByCodigo(getUsuario().getIdAcesso()));
			}
		} catch (SeamCoreException e) {
			throw new SeamWebException(e);
		}

		return PATH_EDITAR_USUARIO;
	}

	public String salvar() throws SeamWebException {

		try {

			usuario.setSenha(getSenhaDigitada());
			setConfirmacaoSenha(getConfirmacaoSenhaDigitada());

			usuario.setSenha(getSenhaDigitada());
			setConfirmacaoSenha(getConfirmacaoSenhaDigitada());
			usuario.setSenhaGerada("S");
			usuario.setStatus(StatusAtivo.STATUS_ATIVO.getValor());
			usuario.setIdAcesso(usuario.getPerfil().getCodigoPerfil());
			usuarioService.save(usuario);

			addMessageInfo("sucesso.salvo");

		} catch (SeamCoreException e) {

			throw new SeamWebException(e);
		}

		return redirecionaUsuarioAcesso(PATH_LISTAR_USUARIO);
	}

	private boolean validaUsuario() throws SeamWebException {

			if (getUsuario().getCodigo() == null
					&& (getUsuario().getLogin() != null && usuarioService
							.getUsuarioByLogin(getUsuario().getLogin(), null) != null)) {

				addMessageError("erro.login.cadastrado");
				return true;
			} else if (getUsuario().getCodigo() != null
					&& validaLoginAtualizaUsuario()) {
				addMessageError("erro.login.cadastrado");
				return true;
			}

			getUsuario().setSenha(getSenhaDigitada());

			if (!getUsuario().getSenha().equals(getConfirmacaoSenhaDigitada())) {
				addMessageError("erro.senha.igual");
				return true;
			}

		return false;
	}

	private boolean validaLoginAtualizaUsuario() {

		Usuario usuario = usuarioService.getUsuarioByLogin(getUsuario()
				.getLogin(), null);

		if (usuario.getCodigo().compareTo(getUsuario().getCodigo()) == 0) {
			return false;
		}

		return true;
	}

	private boolean validaUsuarioAtualizar() throws SeamWebException {

		if (getUsuario().getCodigo() != null
				&& (getSenhaDigitada() == null || getSenhaDigitada().equals(""))) {

			addMessageError("javax.faces.component.UIInput.REQUIRED", "Senha");
			return true;
		}
		if ((getConfirmacaoSenhaDigitada() != null && !getConfirmacaoSenhaDigitada()
				.equals(""))
				&& !getSenhaDigitada().equals(getConfirmacaoSenhaDigitada())) {
			addMessageError("erro.senha.igual");
			return true;
		}

		if (isPerfilGestor()
				&& !usuario.getSenha().equals(getSenhaDigitada())) {
			usuario.setSenhaGerada("S");
			usuario.setSenha(getSenhaDigitada());
		} else {
			usuario.setSenhaGerada("N");
		}
		return false;
	}

	public String atualizar() throws SeamWebException {
		try {

			
			usuarioService.update(usuario);

			addMessageInfo("sucesso.atualizado");

		} catch (SeamCoreException e) {

			throw new SeamWebException(e);
		}

		return redirecionaUsuarioAcesso(PATH_LISTAR_USUARIO);
	}

	public List<Usuario> getListaUsuario() {
		return listaUsuario;
	}

	public void setListaUsuario(List<Usuario> listaUsuario) {
		this.listaUsuario = listaUsuario;
	}

	public Usuario getUsuario() {
		return usuario;
	}

	public void setUsuario(Usuario usuario) {
		this.usuario = usuario;
	}

	public SelectItem[] getListaStatus() {

		listaStatus = new SelectItem[StatusAtivo.getListStatus().size()];

		int i = 0;

		for (StatusAtivo s : StatusAtivo.getListStatus()) {
			listaStatus[i++] = new SelectItem(s.getValor(), s.getDescricao());
		}

		return listaStatus;
	}

	public void setListaStatus(SelectItem[] listaStatus) {
		this.listaStatus = listaStatus;
	}

	public SelectItem[] getListaPerfil() {

		listaPerfil = new SelectItem[Perfil.getListPerfil().size()];

		int i = 0;

		for (Perfil p : Perfil.getListPerfil()) {
			listaPerfil[i++] = new SelectItem(p, p.getDescricao());
		}

		return listaPerfil;
	}

	public void setListaPerfil(SelectItem[] listaPerfil) {
		this.listaPerfil = listaPerfil;
	}

	@Autowired
	public void setUsuarioService(UsuarioService usuarioService) {
		this.usuarioService = usuarioService;
	}

	public Usuario getUsuarioPesquisa() {
		return usuarioPesquisa;
	}

	public void setUsuarioPesquisa(Usuario usuarioPesquisa) {
		this.usuarioPesquisa = usuarioPesquisa;
	}

	@Override
	public String excluir() throws SeamWebException {

		try {
			usuario.setStatus(StatusAtivo.STATUS_INATIVO.getValor());
			usuarioService.update(getUsuario());

			addMessageInfo("sucesso.excluido");

		} catch (SeamCoreException e) {
			throw new SeamWebException(e);
		}

		return PATH_LISTAR_USUARIO;
	}

	public Usuario getUsuarioLogado() {
		if (this.usuarioLogado == null) {
			setUsuarioLogado(recuperaUsuarioLogado());
		}
		return usuarioLogado;
	}

	public void setUsuarioLogado(Usuario usuarioLogado) {
		this.usuarioLogado = usuarioLogado;
	}

	@Override
	public boolean possuiAcesso(Perfil perfil) {
		return !isPerfilGestor();
	}

	public boolean isDesabilitaCadastro() {
		return desabilitaCadastro;
	}

	public boolean isDesabilitaCadastroPerfil() {

		this.desabilitaCadastroPerfil = false;

		if (!isUsuarioNaoCadastrado()) {
			if (getUsuario().getIdAcesso().compareTo(
					Perfil.PERFIL_GESTOR.getCodigoPerfil()) == 0) {
				this.desabilitaCadastroPerfil = true;
			}
		}

		if (isDesabilitaCadastro()) {
			this.desabilitaCadastroPerfil = true;
		}

		return desabilitaCadastroPerfil;
	}

	private boolean isUsuarioNaoCadastrado() {
		return getUsuario().getCodigo() == null;
	}

	public void setDesabilitaCadastro(boolean podeAlterarCadastro) {
		this.desabilitaCadastro = podeAlterarCadastro;
	}

	public String getConfirmacaoSenha() {
		return confirmacaoSenha;
	}

	public void setConfirmacaoSenha(String confirmacaoSenha) {
		this.confirmacaoSenha = confirmacaoSenha;
	}

	public void setDesabilitaCadastroPerfil(boolean desabilitaCadastroPerfil) {
		this.desabilitaCadastroPerfil = desabilitaCadastroPerfil;
	}

	@Override
	public String execute() throws SeamWebException {

		String path = "";

		switch (getAcaoPopUp()) {
		case 1:
			excluir();
			path = pesquisar();
			break;

		case 2:
			path = atualizar();
			break;

		case 3:
			path = salvar();
			break;

		default:
			break;
		}

		return path;
	}

	public String getConfirmacaoSenhaDigitada() {
		return confirmacaoSenhaDigitada;
	}

	public void setConfirmacaoSenhaDigitada(String confirmacaoSenhaDigitada) {
		this.confirmacaoSenhaDigitada = confirmacaoSenhaDigitada;
	}

	public String getSenhaDigitada() {
		return senhaDigitada;
	}

	public void setSenhaDigitada(String senhaDigitada) {
		this.senhaDigitada = senhaDigitada;
	}

	@Override
	public boolean validaForm() throws SeamWebException {

		if (getSenhaDigitada().trim().length() == 0) {
			addMessageError("javax.faces.component.UIInput.REQUIRED", "Senha");
			return true;
		}
		if (getConfirmacaoSenhaDigitada().trim().length() == 0) {
			addMessageError("javax.faces.component.UIInput.REQUIRED",
					"Confirmação da Senha");
			return true;
		}
		setConfirmacaoSenha(getConfirmacaoSenhaDigitada());
		if (getUsuario().getCodigo() != null) {
			return validaUsuarioAtualizar();
		}
		return validaUsuario();
	}

}
